<?php
/**
 * 鉴权中间件
 * @author yupoxiong<i@yupoxiong.com>
 */

declare (strict_types=1);

namespace app\api\middleware;

use app\api\exception\ApiServiceException;
use app\api\service\TokenService;
use Webman\MiddlewareInterface;
use app\common\model\User;
use Webman\Http\Response;
use Webman\Http\Request;

class ApiLoginCheck implements MiddlewareInterface
{
    public function process(Request $request, callable $handler): Response
    {
        $url = get_request_url();

        $request->request_url = $url;

        $url_lower    = strtolower($url);
        $except_lower = array_map('strtolower', API_LOGIN_EXCEPT);

        // 需要验证登录
        if (!in_array($url_lower, $except_lower, false)) {
            $config         = config('api.auth');
            $token_position = $config['token_position'];
            $token_field    = $config['token_field'];
            if ($token_position === 'header') {
                $token = $request->header($token_field, 'token');
            } else {
                $token = $request->input($token_field, 'token');
            }

            // 缺少token
            if (empty($token)) {
                return api_unauthorized('未登录');
            }

            // 验证token
            try {
                $tokenService = new TokenService();

                $jwt = $tokenService->checkToken($token);

                $uid = (int)$jwt->getUid();

                /** @var User $user */
                $user = (new User)->findOrEmpty($uid);
                if ($user->isEmpty()) {
                    return api_unauthorized('用户不存在');
                }

                if ($user->status === 0) {
                    return api_error('账号被冻结');
                }

                $request->user = $user;

            } catch (ApiServiceException $e) {

                $data = [
                    'fail_msg' => $e->getMessage(),
                ];

                return api_unauthorized('验证token失败', $data);
            }
        }

        return $handler($request);
    }
}